#include "../include/node_group.h"
#include "../include/node_data.h"
#include "../include/user_config.h"

#define TOTALNODES 45

NodeGroup node_group(TOTALNODES);

NodeGroup::NodeGroup(int total_nodes): TotalNodes(total_nodes)
{
	for (int i = 0; i < total_nodes; i++)
	{
		NodeData node(i + 1);
		node_list.push_back(node);
	}
}

NodeGroup::~NodeGroup()
{
}

void NodeGroup::updateAllnodesData(dateData begin_date, dateData end_date)
{
	for (int i = 0; i < TotalNodes; i++)
	{
		node_list[i].updateData(begin_date, end_date);
		node_list[i].lable = user_config.user_lables[i];
	}
}

void NodeGroup::updateAllnodesLables()
{
	for (int i = 0; i < TotalNodes; i++)
	{
		node_list[i].lable = user_config.user_lables[i];
	}
}

void NodeGroup::delectAllnodesData(dateData begin_date, dateData end_date)
{
	for (int i = 0; i < TotalNodes; i++)
	{
		node_list[i].delectData(begin_date, end_date);
	}
}

void NodeGroup::pushBackNodeMomentData(int node_id, StampStruct stamp, bool PowerON)
{
	node_list[node_id - 1].pushBackMoment(stamp, PowerON);
	node_list[node_id - 1].saveNodeHisData(stamp.Year, stamp.Month);
}

void NodeGroup::updateNowStamp(StampStruct input_stamp)
{
	dateData temp_day;
	temp_day.Year = input_stamp.Year;
	temp_day.Month = input_stamp.Month;
	temp_day.Day = input_stamp.Day;
	std::vector<NodeData>::iterator node_iter = node_list.begin();
	for (; node_iter != node_list.end(); node_iter++)
	{
		HourMin temp_moment;
		temp_moment.isTamp = true;
		temp_moment.hour = input_stamp.Hour;
		temp_moment.minute = input_stamp.Minute;
		if (node_iter->getDayData(temp_day).size() == 0)
		{
			temp_moment.PowerON = !node_iter->thisDayisElectricAtFirst(temp_day);
		}
		else
		{
			if ((node_iter->getDayData(temp_day).end() - 1)->isTamp)
			{
				temp_moment.PowerON = (node_iter->getDayData(temp_day).end() - 1)->PowerON;
			}
			else
			{
				temp_moment.PowerON = !(node_iter->getDayData(temp_day).end() - 1)->PowerON;
			}
		}
		node_iter->pushBackMoment(input_stamp, temp_moment.PowerON, temp_moment.isTamp);				
	}
}

DayData NodeGroup::getDayData(int node_id, dateData date)
{
	return node_list[node_id - 1].getDayData(date);
}

NodeData NodeGroup::operator [] (int node_id)
{
	return node_list[node_id - 1];
}

void NodeGroup::updateRankMap(dateData begin_date, dateData end_date)
{
	list_id_minute.clear();
	std::vector<NodeData>::iterator node_iter = node_list.begin();
	for (; node_iter != node_list.end(); node_iter++)
	{
		int node_minute = node_iter->getRangeDateMin(begin_date, end_date);
		node_iter->rank_minute = node_minute;
		list_id_minute.push_back(std::pair<int, int>(node_iter->SelfID(), node_minute));
	}
	SortPairVec_Sec(list_id_minute);

	for (int i = 0; i < list_id_minute.size(); i++)
	{
		int id = list_id_minute[i].first;
		int same_sum = 0;
		for (int j = i + 1; j < list_id_minute.size(); j++)
		{
			if (list_id_minute[j].second > list_id_minute[i].second)
				break;
			if (list_id_minute[j].second == list_id_minute[i].second)
				same_sum++;
		}
		node_list[id - 1].rank_order = list_id_minute.size() - i - same_sum;
	}
}

int NodeGroup::getIdByOrder(int order)
{
	return list_id_minute[order - 1].first;
}

void NodeGroup::SortPairVec_Sec(std::vector<std::pair<int, int>>& input_vec)
{
	for (int i = 0; i < input_vec.size() - 1; i++)
	{
		for (int j = 0; j < input_vec.size() - i - 1; j++)
		{
			if (input_vec[j].second > input_vec[j + 1].second)
			{
				std::pair<int, int> temp_pair = input_vec[j];
				input_vec[j] = input_vec[j + 1];
				input_vec[j + 1] = temp_pair;
			}
		}
	}
}